//
//  bitlyfs_Controller.m
//  bitlyfs
//
//  Created by Jay Ridgeway on 1/24/09.
//  Copyright 2009 runcible labs, inc.. All rights reserved.
//
#import "bitlyfs_Controller.h"
#import "bitlyfs_Filesystem.h"
#import <MacFUSE/MacFUSE.h>
#import "BitlyLink.h"

#define kRecentCount    10 // NSDocumentController's _recentsLimit ivar
#define kRecentServers  @"recentservers"
#define kUsernameName   @"username"

#define kFsUserName			@"user"
#define kFsName				@"filesystem"
#define kFsDelegateName		@"delegate"

@implementation bitlyfs_Controller

- (id) awakeFromNib {
	if ([searchField respondsToSelector: @selector(setRecentSearches:)])
	{
		NSMenu* searchMenu = [[[NSMenu alloc] initWithTitle:@"Mounts"] autorelease];
		[searchMenu setAutoenablesItems:YES];
				
		NSMenuItem* recentsTitleItem = [[NSMenuItem alloc] initWithTitle:@"Recent mounts" action:nil keyEquivalent:@""];
		// tag this menu item so NSSearchField can use it and respond to it appropriately
		[recentsTitleItem setTag:NSSearchFieldRecentsTitleMenuItemTag];
		[searchMenu insertItem:recentsTitleItem atIndex:0];
		[recentsTitleItem release];
		
		NSMenuItem* norecentsTitleItem = [[NSMenuItem alloc] initWithTitle:@"No recent mounts" action:nil keyEquivalent:@""];
		// tag this menu item so NSSearchField can use it and respond to it appropriately
		[norecentsTitleItem setTag:NSSearchFieldNoRecentsMenuItemTag];
		[searchMenu insertItem:norecentsTitleItem atIndex:1];
		[norecentsTitleItem release];
		
		NSMenuItem* recentsItem = [[NSMenuItem alloc] initWithTitle:@"Recents" action:nil keyEquivalent:@""];
		// tag this menu item so NSSearchField can use it and respond to it appropriately
		[recentsItem setTag:NSSearchFieldRecentsMenuItemTag];	
		[searchMenu insertItem:recentsItem atIndex:2];
		[recentsItem release];
		
		NSMenuItem* separatorItem = (NSMenuItem*)[NSMenuItem separatorItem];
		// tag this menu item so NSSearchField can use it, by hiding/show it appropriately:
		[separatorItem setTag:NSSearchFieldRecentsTitleMenuItemTag];
		[searchMenu insertItem:separatorItem atIndex:3];
		
		NSMenuItem* clearItem = [[NSMenuItem alloc] initWithTitle:@"Clear" action:nil keyEquivalent:@""];
		[clearItem setTag:NSSearchFieldClearRecentsMenuItemTag];	// tag this menu item so NSSearchField can use it
		[searchMenu insertItem:clearItem atIndex:4];
		[clearItem release];
		
		id searchCell = [searchField cell];
		[searchCell setMaximumRecents:20];
		[searchCell setSearchMenuTemplate:searchMenu];
	}
	_allKeywords = [searchField recentSearches];
	return [super init];
}



- (NSArray*)control:(NSControl*)control textView:(NSTextView *)textView completions:(NSArray*)words forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(int*)index
{
    NSMutableArray*	matches = NULL;
    NSString*		partialString;
    NSArray*		keywords;
    unsigned int	i,count;
    NSString*		string;
	
    partialString = [[textView string] substringWithRange:charRange];
    keywords      = [searchField recentSearches];
    count         = [keywords count];
    matches       = [NSMutableArray array];
	
    // find any match in our keyword array against what was typed -
	for (i=0; i< count; i++)
	{
        string = [keywords objectAtIndex:i];
        if ([string rangeOfString:partialString options:NSAnchoredSearch | NSCaseInsensitiveSearch range:NSMakeRange(0, [string length])].location != NSNotFound)
		{
            [matches addObject:string];
        }
    }
    [matches sortUsingSelector:@selector(compare:)];
	
	return matches;
}

- (void)controlTextDidChange:(NSNotification*)obj
{
	NSTextView* textView = [[obj userInfo] objectForKey:@"NSFieldEditor"];
	
    if (!completePosting && !commandHandling)	// prevent calling "complete" too often
	{
        completePosting = YES;
        [textView complete:nil];
        completePosting = NO;
    }
}

- (BOOL)control:(NSControl*)control textView:(NSTextView*)textView doCommandBySelector:(SEL)commandSelector
{
	if (commandSelector == @selector(insertNewline:)) {
		// enter pressed
		[NSApp stopModal];
		return YES;
    }
	else if ([textView respondsToSelector:commandSelector])
	{
        commandHandling = YES;
        [textView performSelector:commandSelector withObject:nil];
        commandHandling = NO;
    }
    return YES;
}


- (void)mountFailed:(NSNotification *)notification {
  NSDictionary* userInfo = [notification userInfo];
  NSError* error = [userInfo objectForKey:kGMUserFileSystemErrorKey];
  NSLog(@"kGMUserFileSystem Error: %@, userInfo=%@", error, [error userInfo]);  
  NSRunAlertPanel(@"Mount Failed", [error localizedDescription], nil, nil, nil);
  //[[NSApplication sharedApplication] terminate:nil];
}

- (void)didMount:(NSNotification *)notification {
  NSDictionary* userInfo = [notification userInfo];
  NSString* mountPath = [userInfo objectForKey:kGMUserFileSystemMountPathKey];
  NSString* parentPath = [mountPath stringByDeletingLastPathComponent];
  [[NSWorkspace sharedWorkspace] selectFile:mountPath
                   inFileViewerRootedAtPath:parentPath];
}

- (void)didUnmount:(NSNotification*)notification {
	//[[NSApplication sharedApplication] terminate:nil];
}

- (void)applicationDidFinishLaunching:(NSNotification *)notification {
	filesystems = [[NSMutableArray alloc] init];
	_allKeywords = [[NSMutableArray alloc] init];

	[self showConnect:self];
}

- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
	[[NSNotificationCenter defaultCenter] removeObserver:self];
	for (int i=0; i < [filesystems count]; ++i) {
		NSDictionary *fsDict = [filesystems objectAtIndex:i];
		GMUserFileSystem* fs_ = [fsDict objectForKey:kFsName];
		bitlyfs_Controller* fs_delegate_ = [fsDict objectForKey:kFsDelegateName];
		[fs_ unmount];
		[fs_ release];
		[fs_delegate_ release];		
	}
	return NSTerminateNow;
}

- (IBAction)updateFilter:sender
{
    //NSString *searchString = [searchField stringValue];
	
    /*
     Method continues to perform the search and display the results...
     */
}


- (void)timerFireMethod:(NSTimer*)theTimer {
	return;
	NSString *user = [[theTimer userInfo] objectForKey:kFsUserName];
	NSDictionary *fsDict = [theTimer userInfo];
	GMUserFileSystem* fs_ = [fsDict objectForKey:kFsName];
	//bitlyfs_Filesystem* bitlyFS = [fs_ delegate];
	bitlyfs_Filesystem* bitlyFS = [fsDict objectForKey:kFsDelegateName];
	[bitlyFS setLinks:[BitlyLink fetchRecentLinks:user]];
	
    NSLog(@"Timer fired for %@", user);
}

- (IBAction)showConnect:(id)sender {
	int connectResult = [NSApp runModalForWindow:connectPanel_];
	
	if (connectResult == NSRunAbortedResponse) {
		[connectPanel_ orderOut:self];
		return;
	}
	NSString *user = [username stringValue];
	
	[connectPanel_ orderOut:self];
	[self bitlyConnect:user];
}

- (void)bitlyConnect:(NSString *)user {
	NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
	[center addObserver:self selector:@selector(mountFailed:)
				   name:kGMUserFileSystemMountFailed object:nil];
	[center addObserver:self selector:@selector(didMount:)
				   name:kGMUserFileSystemDidMount object:nil];
	[center addObserver:self selector:@selector(didUnmount:)
				   name:kGMUserFileSystemDidUnmount object:nil];
	
	NSString* mountPath = [NSString stringWithFormat:@"/Volumes/%@.bit.ly", user];
	bitlyfs_Filesystem* fs_delegate_ = [[bitlyfs_Filesystem alloc] initWithLinks:[BitlyLink fetchRecentLinks:user]];

	if (fs_delegate_ == nil) {
		[fs_delegate_ release];
		return;
	}
	GMUserFileSystem* fs_ = [[GMUserFileSystem alloc] initWithDelegate:fs_delegate_ isThreadSafe:YES];
	NSDictionary *fsDict = [NSDictionary dictionaryWithObjectsAndKeys:
							fs_delegate_, kFsDelegateName, fs_, kFsName, user, kFsUserName, nil];
	[filesystems addObject:fsDict];
	
	NSMutableArray* options = [NSMutableArray array];
	NSString* volArg = 
    [NSString stringWithFormat:@"volicon=%@", 
		[[NSBundle mainBundle] pathForResource:@"bitlyfs" ofType:@"icns"]];
	[options addObject:volArg];
	[options addObject:[NSString stringWithFormat:@"volname=%@.bit.ly", user]];
	[options addObject:@"rdonly"];
	[fs_ mountAtPath:mountPath withOptions:options];
	
	[NSTimer scheduledTimerWithTimeInterval:10 target:self 
								   selector:@selector(timerFireMethod:)
									userInfo:fsDict repeats:YES];
	
	[_allKeywords insertObject:user atIndex:0];
	[searchField setRecentSearches:_allKeywords];
}	

- (void)windowShouldClose:(id)window {
	[NSApp abortModal];
}


@end
